// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"

#include "LyraCharacterPartTypes.generated.h"

class UChildActorComponent;
class ULyraPawnComponent_CharacterParts;
struct FLyraCharacterPartList;

//////////////////////////////////////////////////////////////////////

// 角色部件碰撞配置模式枚举
UENUM()
enum class ECharacterCustomizationCollisionMode : uint8
{
	// 在生成的角色部件上禁用碰撞
	NoCollision,

	// 使用角色部件自身的碰撞设置
	UseCollisionFromCharacterPart
};

//////////////////////////////////////////////////////////////////////

/**
 * 通过添加角色部件条目创建的句柄，可用于后续移除该部件
 */
USTRUCT(BlueprintType)
struct FLyraCharacterPartHandle
{
	GENERATED_BODY()

	/**
	 * 重置句柄
	 */
	void Reset()
	{
		PartHandle = INDEX_NONE;
	}

	/**
	 * 检查句柄是否有效
	 */
	bool IsValid() const
	{
		return PartHandle != INDEX_NONE;
	}

private:
	UPROPERTY()
	int32 PartHandle = INDEX_NONE; // 部件句柄索引

	friend FLyraCharacterPartList;
};

//////////////////////////////////////////////////////////////////////
// 角色部件请求

/**
 * 角色部件数据结构
 */
USTRUCT(BlueprintType)
struct FLyraCharacterPart
{
	GENERATED_BODY()

	// 要生成的部件类
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TSubclassOf<AActor> PartClass;

	// 附加部件的插槽名称（如果有）
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FName SocketName;

	// 如何处理部件中原始组件的碰撞
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	ECharacterCustomizationCollisionMode CollisionMode = ECharacterCustomizationCollisionMode::NoCollision;

	/**
	 * 比较两个部件是否等效，忽略碰撞模式
	 */
	static bool AreEquivalentParts(const FLyraCharacterPart& A, const FLyraCharacterPart& B)
	{
		return (A.PartClass == B.PartClass) && (A.SocketName == B.SocketName);
	}
};